home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / lockd / lockd.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  11.1 KB  |  375 lines

  1. /*
  2.  * linux/include/linux/lockd/lockd.h
  3.  *
  4.  * General-purpose lockd include file.
  5.  *
  6.  * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
  7.  */
  8.  
  9. #ifndef LINUX_LOCKD_LOCKD_H
  10. #define LINUX_LOCKD_LOCKD_H
  11.  
  12. #ifdef __KERNEL__
  13.  
  14. #include <linux/in.h>
  15. #include <linux/in6.h>
  16. #include <net/ipv6.h>
  17. #include <linux/fs.h>
  18. #include <linux/kref.h>
  19. #include <linux/utsname.h>
  20. #include <linux/nfsd/nfsfh.h>
  21. #include <linux/lockd/bind.h>
  22. #include <linux/lockd/xdr.h>
  23. #ifdef CONFIG_LOCKD_V4
  24. #include <linux/lockd/xdr4.h>
  25. #endif
  26. #include <linux/lockd/debug.h>
  27.  
  28. /*
  29.  * Version string
  30.  */
  31. #define LOCKD_VERSION        "0.5"
  32.  
  33. /*
  34.  * Default timeout for RPC calls (seconds)
  35.  */
  36. #define LOCKD_DFLT_TIMEO    10
  37.  
  38. /*
  39.  * Lockd host handle (used both by the client and server personality).
  40.  */
  41. struct nlm_host {
  42.     struct hlist_node    h_hash;        /* doubly linked list */
  43.     struct sockaddr_storage    h_addr;        /* peer address */
  44.     size_t            h_addrlen;
  45.     struct sockaddr_storage    h_srcaddr;    /* our address (optional) */
  46.     struct rpc_clnt    *    h_rpcclnt;    /* RPC client to talk to peer */
  47.     char *            h_name;        /* remote hostname */
  48.     u32            h_version;    /* interface version */
  49.     unsigned short        h_proto;    /* transport proto */
  50.     unsigned short        h_reclaiming : 1,
  51.                 h_server     : 1, /* server side, not client side */
  52.                 h_inuse      : 1;
  53.     wait_queue_head_t    h_gracewait;    /* wait while reclaiming */
  54.     struct rw_semaphore    h_rwsem;    /* Reboot recovery lock */
  55.     u32            h_state;    /* pseudo-state counter */
  56.     u32            h_nsmstate;    /* true remote NSM state */
  57.     u32            h_pidcount;    /* Pseudopids */
  58.     atomic_t        h_count;    /* reference count */
  59.     struct mutex        h_mutex;    /* mutex for pmap binding */
  60.     unsigned long        h_nextrebind;    /* next portmap call */
  61.     unsigned long        h_expires;    /* eligible for GC */
  62.     struct list_head    h_lockowners;    /* Lockowners for the client */
  63.     spinlock_t        h_lock;
  64.     struct list_head    h_granted;    /* Locks in GRANTED state */
  65.     struct list_head    h_reclaim;    /* Locks in RECLAIM state */
  66.     struct nsm_handle *    h_nsmhandle;    /* NSM status handle */
  67.  
  68.     char            h_addrbuf[48],    /* address eyecatchers */
  69.                 h_srcaddrbuf[48];
  70. };
  71.  
  72. struct nsm_handle {
  73.     struct list_head    sm_link;
  74.     atomic_t        sm_count;
  75.     char *            sm_name;
  76.     struct sockaddr_storage    sm_addr;
  77.     size_t            sm_addrlen;
  78.     unsigned int        sm_monitored : 1,
  79.                 sm_sticky : 1;    /* don't unmonitor */
  80.     char            sm_addrbuf[48];    /* address eyecatcher */
  81. };
  82.  
  83. /*
  84.  * Rigorous type checking on sockaddr type conversions
  85.  */
  86. static inline struct sockaddr_in *nlm_addr_in(const struct nlm_host *host)
  87. {
  88.     return (struct sockaddr_in *)&host->h_addr;
  89. }
  90.  
  91. static inline struct sockaddr *nlm_addr(const struct nlm_host *host)
  92. {
  93.     return (struct sockaddr *)&host->h_addr;
  94. }
  95.  
  96. static inline struct sockaddr_in *nlm_srcaddr_in(const struct nlm_host *host)
  97. {
  98.     return (struct sockaddr_in *)&host->h_srcaddr;
  99. }
  100.  
  101. static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host)
  102. {
  103.     return (struct sockaddr *)&host->h_srcaddr;
  104. }
  105.  
  106. static inline struct sockaddr_in *nsm_addr_in(const struct nsm_handle *handle)
  107. {
  108.     return (struct sockaddr_in *)&handle->sm_addr;
  109. }
  110.  
  111. static inline struct sockaddr *nsm_addr(const struct nsm_handle *handle)
  112. {
  113.     return (struct sockaddr *)&handle->sm_addr;
  114. }
  115.  
  116. /*
  117.  * Map an fl_owner_t into a unique 32-bit "pid"
  118.  */
  119. struct nlm_lockowner {
  120.     struct list_head list;
  121.     atomic_t count;
  122.  
  123.     struct nlm_host *host;
  124.     fl_owner_t owner;
  125.     uint32_t pid;
  126. };
  127.  
  128. struct nlm_wait;
  129.  
  130. /*
  131.  * Memory chunk for NLM client RPC request.
  132.  */
  133. #define NLMCLNT_OHSIZE        ((__NEW_UTS_LEN) + 10u)
  134. struct nlm_rqst {
  135.     atomic_t        a_count;
  136.     unsigned int        a_flags;    /* initial RPC task flags */
  137.     struct nlm_host *    a_host;        /* host handle */
  138.     struct nlm_args        a_args;        /* arguments */
  139.     struct nlm_res        a_res;        /* result */
  140.     struct nlm_block *    a_block;
  141.     unsigned int        a_retries;    /* Retry count */
  142.     u8            a_owner[NLMCLNT_OHSIZE];
  143. };
  144.  
  145. /*
  146.  * This struct describes a file held open by lockd on behalf of
  147.  * an NFS client.
  148.  */
  149. struct nlm_file {
  150.     struct hlist_node    f_list;        /* linked list */
  151.     struct nfs_fh        f_handle;    /* NFS file handle */
  152.     struct file *        f_file;        /* VFS file pointer */
  153.     struct nlm_share *    f_shares;    /* DOS shares */
  154.     struct list_head    f_blocks;    /* blocked locks */
  155.     unsigned int        f_locks;    /* guesstimate # of locks */
  156.     unsigned int        f_count;    /* reference count */
  157.     struct mutex        f_mutex;    /* avoid concurrent access */
  158. };
  159.  
  160. /*
  161.  * This is a server block (i.e. a lock requested by some client which
  162.  * couldn't be granted because of a conflicting lock).
  163.  */
  164. #define NLM_NEVER        (~(unsigned long) 0)
  165. /* timeout on non-blocking call: */
  166. #define NLM_TIMEOUT        (7 * HZ)
  167.  
  168. struct nlm_block {
  169.     struct kref        b_count;    /* Reference count */
  170.     struct list_head    b_list;        /* linked list of all blocks */
  171.     struct list_head    b_flist;    /* linked list (per file) */
  172.     struct nlm_rqst    *    b_call;        /* RPC args & callback info */
  173.     struct svc_serv *    b_daemon;    /* NLM service */
  174.     struct nlm_host *    b_host;        /* host handle for RPC clnt */
  175.     unsigned long        b_when;        /* next re-xmit */
  176.     unsigned int        b_id;        /* block id */
  177.     unsigned char        b_granted;    /* VFS granted lock */
  178.     struct nlm_file *    b_file;        /* file in question */
  179.     struct cache_req *    b_cache_req;    /* deferred request handling */
  180.     struct file_lock *    b_fl;        /* set for GETLK */
  181.     struct cache_deferred_req * b_deferred_req;
  182.     unsigned int        b_flags;    /* block flags */
  183. #define B_QUEUED        1    /* lock queued */
  184. #define B_GOT_CALLBACK        2    /* got lock or conflicting lock */
  185. #define B_TIMED_OUT        4    /* filesystem too slow to respond */
  186. };
  187.  
  188. /*
  189.  * Global variables
  190.  */
  191. extern struct rpc_program    nlm_program;
  192. extern struct svc_procedure    nlmsvc_procedures[];
  193. #ifdef CONFIG_LOCKD_V4
  194. extern struct svc_procedure    nlmsvc_procedures4[];
  195. #endif
  196. extern int            nlmsvc_grace_period;
  197. extern unsigned long        nlmsvc_timeout;
  198. extern int            nsm_use_hostnames;
  199.  
  200. /*
  201.  * Lockd client functions
  202.  */
  203. struct nlm_rqst * nlm_alloc_call(struct nlm_host *host);
  204. void          nlm_release_call(struct nlm_rqst *);
  205. int          nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
  206. int          nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
  207. struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl);
  208. void          nlmclnt_finish_block(struct nlm_wait *block);
  209. int          nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
  210. __be32          nlmclnt_grant(const struct sockaddr *addr,
  211.                 const struct nlm_lock *lock);
  212. void          nlmclnt_recovery(struct nlm_host *);
  213. int          nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
  214. void          nlmclnt_next_cookie(struct nlm_cookie *);
  215.  
  216. /*
  217.  * Host cache
  218.  */
  219. struct nlm_host  *nlmclnt_lookup_host(const struct sockaddr *sap,
  220.                     const size_t salen,
  221.                     const unsigned short protocol,
  222.                     const u32 version,
  223.                     const char *hostname);
  224. struct nlm_host  *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
  225.                     const char *hostname,
  226.                     const size_t hostname_len);
  227. struct rpc_clnt * nlm_bind_host(struct nlm_host *);
  228. void          nlm_rebind_host(struct nlm_host *);
  229. struct nlm_host * nlm_get_host(struct nlm_host *);
  230. void          nlm_release_host(struct nlm_host *);
  231. void          nlm_shutdown_hosts(void);
  232. extern void      nlm_host_rebooted(const struct sockaddr_in *, const char *,
  233.                     unsigned int, u32);
  234. void          nsm_release(struct nsm_handle *);
  235.  
  236.  
  237. /*
  238.  * This is used in garbage collection and resource reclaim
  239.  * A return value != 0 means destroy the lock/block/share
  240.  */
  241. typedef int      (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
  242.  
  243. /*
  244.  * Server-side lock handling
  245.  */
  246. __be32          nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
  247.                   struct nlm_host *, struct nlm_lock *, int,
  248.                   struct nlm_cookie *, int);
  249. __be32          nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
  250. __be32          nlmsvc_testlock(struct svc_rqst *, struct nlm_file *,
  251.             struct nlm_host *, struct nlm_lock *,
  252.             struct nlm_lock *, struct nlm_cookie *);
  253. __be32          nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
  254. unsigned long      nlmsvc_retry_blocked(void);
  255. void          nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
  256.                     nlm_host_match_fn_t match);
  257. void          nlmsvc_grant_reply(struct nlm_cookie *, __be32);
  258.  
  259. /*
  260.  * File handling for the server personality
  261.  */
  262. __be32          nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
  263.                     struct nfs_fh *);
  264. void          nlm_release_file(struct nlm_file *);
  265. void          nlmsvc_mark_resources(void);
  266. void          nlmsvc_free_host_resources(struct nlm_host *);
  267. void          nlmsvc_invalidate_all(void);
  268.  
  269. /*
  270.  * Cluster failover support
  271.  */
  272. int           nlmsvc_unlock_all_by_sb(struct super_block *sb);
  273. int           nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
  274.  
  275. static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
  276. {
  277.     return file->f_file->f_path.dentry->d_inode;
  278. }
  279.  
  280. static inline int __nlm_privileged_request4(const struct sockaddr *sap)
  281. {
  282.     const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
  283.     return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
  284.             (ntohs(sin->sin_port) < 1024);
  285. }
  286.  
  287. #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  288. static inline int __nlm_privileged_request6(const struct sockaddr *sap)
  289. {
  290.     const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  291.     return (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK) &&
  292.             (ntohs(sin6->sin6_port) < 1024);
  293. }
  294. #else    /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
  295. static inline int __nlm_privileged_request6(const struct sockaddr *sap)
  296. {
  297.     return 0;
  298. }
  299. #endif    /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
  300.  
  301. /*
  302.  * Ensure incoming requests are from local privileged callers.
  303.  *
  304.  * Return TRUE if sender is local and is connecting via a privileged port;
  305.  * otherwise return FALSE.
  306.  */
  307. static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
  308. {
  309.     const struct sockaddr *sap = svc_addr(rqstp);
  310.  
  311.     switch (sap->sa_family) {
  312.     case AF_INET:
  313.         return __nlm_privileged_request4(sap);
  314.     case AF_INET6:
  315.         return __nlm_privileged_request6(sap);
  316.     default:
  317.         return 0;
  318.     }
  319. }
  320.  
  321. static inline int __nlm_cmp_addr4(const struct sockaddr *sap1,
  322.                   const struct sockaddr *sap2)
  323. {
  324.     const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
  325.     const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
  326.     return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
  327. }
  328.  
  329. static inline int __nlm_cmp_addr6(const struct sockaddr *sap1,
  330.                   const struct sockaddr *sap2)
  331. {
  332.     const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
  333.     const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
  334.     return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
  335. }
  336.  
  337. /*
  338.  * Compare two host addresses
  339.  *
  340.  * Return TRUE if the addresses are the same; otherwise FALSE.
  341.  */
  342. static inline int nlm_cmp_addr(const struct sockaddr *sap1,
  343.                    const struct sockaddr *sap2)
  344. {
  345.     if (sap1->sa_family == sap2->sa_family) {
  346.         switch (sap1->sa_family) {
  347.         case AF_INET:
  348.             return __nlm_cmp_addr4(sap1, sap2);
  349.         case AF_INET6:
  350.             return __nlm_cmp_addr6(sap1, sap2);
  351.         }
  352.     }
  353.     return 0;
  354. }
  355.  
  356. /*
  357.  * Compare two NLM locks.
  358.  * When the second lock is of type F_UNLCK, this acts like a wildcard.
  359.  */
  360. static inline int nlm_compare_locks(const struct file_lock *fl1,
  361.                     const struct file_lock *fl2)
  362. {
  363.     return    fl1->fl_pid   == fl2->fl_pid
  364.          && fl1->fl_owner == fl2->fl_owner
  365.          && fl1->fl_start == fl2->fl_start
  366.          && fl1->fl_end   == fl2->fl_end
  367.          &&(fl1->fl_type  == fl2->fl_type || fl2->fl_type == F_UNLCK);
  368. }
  369.  
  370. extern struct lock_manager_operations nlmsvc_lock_operations;
  371.  
  372. #endif /* __KERNEL__ */
  373.  
  374. #endif /* LINUX_LOCKD_LOCKD_H */
  375.